package groupon.common.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;

@SuppressWarnings("rawtypes") 
public class GroupOnContainerEntityManagerFactoryBean implements
		BeanFactoryPostProcessor, PersistenceUnitPostProcessor {

	private List<Class> _managedClasses;
	private String _entityManagerFactory;

	public List<Class> getManagedClasses() {
		return _managedClasses;
	}

	@Required
	public void setManagedClasses(List<Class> managedClasses) {
		_managedClasses = managedClasses;
	}

	public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
		for (Class clazz : _managedClasses) {
			pui.addManagedClassName(clazz.getName());
		}
	}

	public void postProcessBeanFactory(
			ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition entityManagerFactoryDefinition = beanFactory
				.getBeanDefinition(_entityManagerFactory);
		PropertyValue propertyValue = entityManagerFactoryDefinition
				.getPropertyValues().getPropertyValue(
						"persistenceUnitPostProcessors");

		if (propertyValue != null) {
			PersistenceUnitPostProcessor[] puiPostProcessor = (PersistenceUnitPostProcessor[]) entityManagerFactoryDefinition
					.getPropertyValues()
					.getPropertyValue("persistenceUnitPostProcessors")
					.getValue();

			List<PersistenceUnitPostProcessor> ppList = new ArrayList<PersistenceUnitPostProcessor>();
			ppList.addAll(Arrays.asList(puiPostProcessor));
			ppList.add(this);
			propertyValue = new PropertyValue("persistenceUnitPostProcessors",
					ppList.toArray(new PersistenceUnitPostProcessor[0]));
			entityManagerFactoryDefinition.getPropertyValues()
					.addPropertyValue(propertyValue);
		} else {
			PersistenceUnitPostProcessor[] pp = new PersistenceUnitPostProcessor[1];
			pp[0] = this;
			propertyValue = new PropertyValue("persistenceUnitPostProcessors",
					pp);
			entityManagerFactoryDefinition.getPropertyValues()
					.addPropertyValue(propertyValue);
		}

	}

	public String getEntityManagerFactory() {
		return _entityManagerFactory;
	}

	@Required
	public void setEntityManagerFactory(String entityManagerFactory) {
		_entityManagerFactory = entityManagerFactory;
	}

}
